/**
 * @Project TMHSC
 * @Author Tran Manh Hung
 * @Email: hungtmit@gmail.com | tmh@xwebgate.com
 * @Copyright © 2011 TMH. All rights reserved
 * @Createdate Feb 9, 2011
 * @Createtime 2:19:44 PM
 */

package com.tmh.study.fMVW
{
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.geom.Point;
	import flash.net.URLLoader;
	import flash.net.URLRequest;

	public class IsometricTile extends Sprite
	{
		private var _map:Array;

		private var _gridWidth:Number = 48;

		private var _gridHeight:Number = 24;

		private var _mapHolder:MovieClip;

		public function IsometricTile()
		{
			addEventListener(Event.ADDED_TO_STAGE, init);
		}

		private function init(e:Event):void
		{
			// An URLLoader is needed to load an external text file.
			var loader:URLLoader = new URLLoader();

			/* In order to know when the external text file is loaded, we need
			to listen to the COMPLETE event and handle it in the onMapDataLoaded
			function. */
			loader.addEventListener(Event.COMPLETE, onMapDataLoaded);

			/* After setting up the loader, we will actually load the file.
			The filename is defined as mapdata.xml in this example. The filename
			can be dynamically set in the future to load different map data
			according to the needs. */
			loader.load(new URLRequest('assets/mapdata.xml'));
		}

		private function onMapDataLoaded(e:Event):void
		{
			_mapHolder = new MovieClip();

			/* The loaded XML data is stored in the loader.data. The e.target
			is the target of the COMPLETE event which refer to the loader we used
			to load the map data. We create an XML object to parse the map data. */
			var _xml:XML = new XML(e.target.data);

			/* The width and height as children under root node so we can
			directly access them and type casting it into integer. */
			var mapWidth:int = int(_xml.width);
			var mapHeight:int = int(_xml.height);

			/* For the terrain data, they are stored as comma separated number
			with line break for every row. We can prepare the terrain data by
			trimming the white space and break it into rows. */
			var terrainString:String = _xml.terrain;
			terrainString = terrainString.split("\t").join('');

			var terrainData:Array = terrainString.split("\n");

			// parse the terrain data
			_map = new Array();

			for (var i:int = 0; i < mapHeight; i++)
			{
				_map[i] = new Array();
				var mapRowData:Array = terrainData[i + 1].split(",");

				for (var j:int = 0; j < mapWidth; j++)
				{
					_map[i][j] = new IsoTile();
					_mapHolder.addChild(_map[i][j]);
					_map[i][j].x = (j - i) * _gridWidth / 2;
					_map[i][j].y = (i + j) * _gridHeight / 2;
					_map[i][j].gotoAndStop(mapRowData[j]);
				}
			}

			addChild(_mapHolder);
			_mapHolder.x = (stage.stageWidth - _gridWidth) / 2;
			_mapHolder.y = (stage.stageHeight - _mapHolder.height) / 2;
		}

		private function i2s(ix:Number, iy:Number):Point
		{
			var sx:Number = (ix - iy) * _gridWidth / 2;
			var sy:Number = (ix + iy) * _gridHeight / 2;

			return _mapHolder.localToGlobal(new Point(sx, sy));
		}

		private function s2i(sx:Number, sy:Number):Point
		{
			var localPoint:Point = _mapHolder.globalToLocal(new Point(sx, sy));

			var sx:Number = localPoint.x;

			var sy:Number = localPoint.y;

			var ix:Number = Math.floor((sy * _gridWidth + sx * _gridHeight) / (_gridHeight * _gridWidth));
			var iy:Number = Math.floor((sy * _gridWidth - sx * _gridHeight) / (_gridHeight * _gridWidth)) + 1;

			return new Point(ix, iy);
		}

		public function s2iLocal(sx:Number, sy:Number):Point
		{
			var ix:int = Math.floor((sy * _gridWidth + sx * _gridHeight) / (_gridHeight * _gridWidth));
			var iy:int = Math.floor((sy * _gridWidth - sx * _gridHeight) / (_gridHeight * _gridWidth)) + 1;
			return new Point(ix, iy);
		}

		public function i2sLocal(ix:int, iy:int):Point
		{
			var sx:Number = (ix - iy) * _gridWidth / 2 + _gridWidth / 2;
			var sy:Number = (ix + iy) * _gridHeight / 2;
			return new Point(sx, sy);
		}
	}
}